package com.mt.lulucai;

import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.mt.lulucai.bean.ReciveMsg;
import com.mt.lulucai.bean.gsonentity.SendGsonEntity;
import com.mt.lulucai.constant.Constant;
import com.mt.lulucai.ui.BaseActivity;
import com.mt.lulucai.usbdriver.help.GlobalVariable;
import com.mt.lulucai.usbdriver.help.HexUtil;
import com.mt.lulucai.usbdriver.help.ICallBack;
import com.mt.lulucai.usbdriver.help.MyUsbDriver;
import com.mt.lulucai.util.PermissionsManager;
import com.mt.lulucai.util.TcpHelper;
import com.mt.lulucai.widget.TipsDialog;


import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.CRC32;

//串口处理类
public class MainActivity extends BaseActivity implements View.OnClickListener {

    private GlobalVariable mGlobalVariable;
    public static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
    private PermissionsManager permissionsManager;
    private UsbManager mUsbManager;
    private MyUsbDriver mMyUsbDriver;

    private ReadThread mReadThread;
    private Button mTestBtn;
    private Button mTestBtn2;
    private Button mTestBtn3;
    private ImageView mQRImageView;

    private ScrollView mScrollView;
    private TextView mDumpTextView;

    private String imeiString;
    private String ip;
    private String port;
    private String qrUrl = "https://m.hrwb.net/wx/MT2005K35000545.do";
    private HexUtil mHexUtil = new HexUtil();
    private TcpHelper tTcpHelper = new TcpHelper();


    private TcpHelper.TcpListener mTcpListener =  new TcpHelper.TcpListener() {
        @Override
        public void onFail(String returnData) {
            Message msg = Message.obtain();
            msg.what = 3;
            msg.obj = returnData;
            mHandler.sendMessage(msg);
        }

        @Override
        public void onSuccess(String returnData) {
            Message msg = Message.obtain();
            msg.what = 2;
            msg.obj = returnData;
            mHandler.sendMessage(msg);
            sendMsg(returnData);
        }
    };

    ICallBack callBack = new ICallBack() {
        @Override
        public void onReciveData(ReciveMsg reciveMsg) {
            String rcvStr =  reciveMsg.getReciveDataString();
            Message msg = Message.obtain();
            msg.what = 1;
            msg.obj = rcvStr;
            mHandler.sendMessage(msg);
            rcvStr = rcvStr.replaceAll("#llc#","");
            final Gson tGson = new Gson();
            SendGsonEntity tSendGsonEntity = tGson.fromJson(rcvStr,SendGsonEntity.class);
            String type = tSendGsonEntity.getType();
            imeiString="";
            if ("50".equals(type)){
                final Map<String, Object> returnGson = new HashMap<String, Object>();
                CRC32 crc32 = new CRC32();
                long timestamp = (System.currentTimeMillis()/1000L);
                String security = "llcSecurity2020";
                String sim = "";
                String tmlNo = "MT2005K35000545";
                crc32.update((security+timestamp+tmlNo).getBytes());
                returnGson.put("type", 50);
                returnGson.put("timestamp", timestamp);
                returnGson.put("imei", imeiString);
                returnGson.put("SIM", sim);
                returnGson.put("tmlNo", tmlNo);
                returnGson.put("securityKey", crc32.getValue());
                Map<String, Object> returnDataGson = new HashMap<String, Object>();
                int signal  = 5;
                returnDataGson.put("signal", signal);
                TcpHelper tTcpHelper = new TcpHelper();
                Map<String,String> paramMap = new HashMap<String, String>();
                ip = tSendGsonEntity.getData().getTcp();
                port = tSendGsonEntity.getData().getPort();
                paramMap.put("Ip",ip);
                paramMap.put("tcpPort",port);
                paramMap.put("security",security);
                paramMap.put("imei",imeiString);
                paramMap.put("tmlNo",tmlNo);
                returnDataGson.put("status", 0);
                returnGson.put("data", returnDataGson);
                String json = new Gson().toJson(returnGson);
                sendMsg(json);
            }else{
                Map<String,String> paramMap = new HashMap<String, String>();
                paramMap.put("Ip",ip);
                paramMap.put("tcpPort",port);
                paramMap.put("tcpString",reciveMsg.getReciveDataString());
                tTcpHelper.sendCommonRequest(paramMap);
            }

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initData();

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        permissionsManager = new PermissionsManager(this);
        boolean granted = permissionsManager.isPermissionGranted(PermissionsManager.ACCESS_FINE_LOCATION);
        if (!granted) {
            permissionsManager.requestPermission(PermissionsManager.ACCESS_FINE_LOCATION);
        }
        boolean granted1 = permissionsManager.isPermissionGranted(PermissionsManager.ACCESS_COARSE_LOCATION);
        if (!granted1) {
            permissionsManager.requestPermission(PermissionsManager.ACCESS_COARSE_LOCATION);
        }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
        }


        TelephonyManager telephonyManager = (TelephonyManager)this.getApplicationContext().getSystemService( Context.TELEPHONY_SERVICE );
        imeiString = telephonyManager.getDeviceId();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected boolean toggleOverridePendingTransition() {
        return false;
    }

    @Override
    protected Constant.TransitionMode getOverridePendingTransitionMode() {
        return null;
    }

    public void initView() {
        mScrollView = this.findViewById(R.id.demoScroller);
        mDumpTextView = this.findViewById(R.id.consoleText);
        mTestBtn = this.findViewById(R.id.testBtn);
        mTestBtn2 = this.findViewById(R.id.testBtn2);
        mTestBtn3 = this.findViewById(R.id.testBtn3);
        mQRImageView = this.findViewById(R.id.QRImageView);
    }

    public void initData() {
        mGlobalVariable = GlobalVariable.getinstance();
        mGlobalVariable.setOpen(false);
        mMyUsbDriver = new MyUsbDriver();
        mTestBtn.setOnClickListener(this);
        mTestBtn2.setOnClickListener(this);
        mTestBtn3.setOnClickListener(this);
        tTcpHelper.settTcpListener(mTcpListener);
//        usbDriverConnect();
        Bitmap tBitmap = generateBitmap(qrUrl,200,200);
        mQRImageView.setImageBitmap(tBitmap);
    }



    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.finish();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }


    private void sendMsg(String sendMsg){
        String sendStr = "";
        if(sendMsg!=null && sendMsg.contains("#llc#") ){
            sendStr = mHexUtil.bytesToHexString(sendMsg.getBytes());
        }else{
            sendStr = mHexUtil.bytesToHexString((sendMsg+"#llc#").getBytes());
        }

        int length = sendStr.length()/2+4;
        String hexLength = getFormatStr(Integer.toHexString(length),4);
        sendStr = "AAEE"+hexLength+sendStr;
        Message msg = Message.obtain();
        msg.what = 4;
        try {
            mGlobalVariable.sendMsg(sendStr);
            msg.obj = sendStr;
            mHandler.sendMessage(msg);
        } catch (Exception e) {
            e.printStackTrace();
            msg.obj = "fail"+e.getMessage();
            mHandler.sendMessage(msg);
        }
    }

    public void usbDriverConnect() {
        // 智能识别设备
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        List<UsbSerialDriver> drivers = UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);
        if (drivers.size() > 0) {
            List<UsbSerialPort> ports = drivers.get(0).getPorts();
            if (ports.size() == 1) {
                mGlobalVariable.sPort = ports.get(0);
                UsbDevice device = mGlobalVariable.sPort.getDriver().getDevice();
                if (!mUsbManager.hasPermission(device)) {
                    PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
                    mUsbManager.requestPermission(device, usbPermissionIntent);
                    return;
                }
            } else {
                final TipsDialog tTipsDialog = TipsDialog.getInstance("", getString(R.string.no_usb_host));
                tTipsDialog.show(getSupportFragmentManager(), TAG_LOG);
                return;
            }

        } else {
            final TipsDialog tTipsDialog = TipsDialog.getInstance("", getString(R.string.no_usb_host));
            tTipsDialog.show(getSupportFragmentManager(), TAG_LOG);
            return;
        }
        UsbDeviceConnection connection = mUsbManager.openDevice(mGlobalVariable.sPort.getDriver().getDevice());
        if (connection == null) {
            final TipsDialog tTipsDialog = TipsDialog.getInstance("", getString(R.string.open_fail));
            tTipsDialog.show(getSupportFragmentManager(), TAG_LOG);
            return;
        }
        try {
            mGlobalVariable.sPort.open(connection);
            //配置串口波特率，函数说明可参照编程手册
            mGlobalVariable.sPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
            Toast.makeText(this, R.string.open_success, Toast.LENGTH_SHORT).show();
            if (mReadThread == null) {
                mReadThread = new ReadThread();
                mReadThread.start();
            }
            //发送开始测量
            mMyUsbDriver.sendStartMeasure();
        }catch (IOException e) {
                final TipsDialog tTipsDialog = TipsDialog.getInstance("", getString(R.string.open_fail));
                tTipsDialog.show(getSupportFragmentManager(), TAG_LOG);
                try {
                    mGlobalVariable.sPort.close();
                } catch (IOException e2) {
                    // Ignore.
                }
                mGlobalVariable.sPort = null;
                return;
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    @Override
    public void onClick(View view) {
        String rcvMag ="";
        switch (view.getId()) {
            case R.id.testBtn:
                rcvMag = mHexUtil.bytesToHexString("{\"data\":{\"tcp\":\"v2-tml.lulucai.cn\",\"port\":9797},\"securityKey\":603967602,\"type\":\"50\",\"timestamp\":1599443002}".getBytes());
                int length = rcvMag.length()/2+4;
                String hexLength = getFormatStr(Integer.toHexString(length),4);
                rcvMag = "AAEE"+hexLength+rcvMag;
                mGlobalVariable.readMsg(rcvMag, callBack);
                rcvMag = "AA EE 01 0C 7B 22 74 79 70 65 22 3A 31 2C 22 74 69 6D 65 73 74 61 6D 70 22 3A 31 35 39 39 31 39 32 32 32 37 2C 22 69 6D 65 69 22 3A 22 38 36 37 35 36 37 30 34 32 35 32 31 31 35 33 22 2C 22 53 49 4D 22 3A 22 38 39 38 36 30 34 32 33 31 39 31 39 39 33 31 31 38 37 35 38 22 2C 22 64 61 74 61 22 3A 7B 22 74 6D 6C 45 72 72 6F 72 46 6C 61 67 22 3A 30 2C 22 68 75 6D 61 6E 53 65 6E 73 6F 72 22 3A 30 2C 22 73 69 67 6E 61 6C 22 3A 35 2C 22 74 6D 6C 56 65 72 73 69 6F 6E 22 3A 22 74 78 5F 70 6C 5F 6B 33 36 5F 32 2E 32 5F 32 2E 34 22 2C 22 73 65 6E 73 6F 72 22 3A 7B 22 53 50 4D 54 22 3A 30 2C 22 44 43 4D 54 22 3A 30 2C 22 53 53 31 22 3A 31 2C 22 53 53 32 22 3A 31 2C 22 53 53 33 22 3A 30 2C 22 53 53 34 22 3A 31 7D 7D 2C 22 73 65 63 75 72 69 74 79 4B 65 79 22 3A 22 35 30 30 30 36 39 61 39 22 7D 23 6C 6C 63 23";
                mGlobalVariable.readMsg(rcvMag, callBack);
                break;
            case R.id.testBtn2:
//                rcvMag = "AA EE 00 F0 7B 22 74 79 70 65 22 3A 32 2C 22 74 69 6D 65 73 74 61 6D 70 22 3A 31 35 39 39 31 39 32 32 32 38 2C 22 74 6D 6C 4E 6F 22 3A 22 4D 54 32 30 30 35 4B 33 35 30 30 30 35 34 35 22 2C 22 64 61 74 61 22 3A 7B 22 74 6D 6C 45 72 72 6F 72 46 6C 61 67 22 3A 30 2C 22 68 75 6D 61 6E 53 65 6E 73 6F 72 22 3A 30 2C 22 73 69 67 6E 61 6C 22 3A 35 2C 22 74 6D 6C 56 65 72 73 69 6F 6E 22 3A 22 74 78 5F 70 6C 5F 6B 33 36 5F 32 2E 32 5F 32 2E 34 22 2C 22 73 65 6E 73 6F 72 22 3A 7B 22 53 50 4D 54 22 3A 30 2C 22 44 43 4D 54 22 3A 30 2C 22 53 53 31 22 3A 31 2C 22 53 53 32 22 3A 31 2C 22 53 53 33 22 3A 30 2C 22 53 53 34 22 3A 31 7D 7D 2C 22 73 65 63 75 72 69 74 79 4B 65 79 22 3A 22 33 37 31 61 30 63 63 63 22 7D 23 6C 6C 63 23";
//                mGlobalVariable.readMsg(rcvMag, callBack);
                usbDriverConnect();
                break;

            case R.id.testBtn3:
                mDumpTextView.setText("");
                mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
                break;
            default:
                break;
        }
    }

    /**
     * 格式化string前补0
     * @param str
     * @param length
     * @return
     */
    private String getFormatStr(String str,int length){
        StringBuilder sb = new StringBuilder();
        while(sb.length()<(length-str.length())){
            sb.append("0");
        }
        sb.append(str);
        return sb.toString();
    }


    class ReadThread extends Thread {
        @Override
        public void run() {
            do {
                try {
                    String readMsg = mGlobalVariable.readMsg();
                    if(readMsg!=null){
                        mGlobalVariable.readMsg(readMsg, callBack);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } while (true);
        }
    }

//    class SendThread extends Thread {
//        @Override
//        public void run() {
//            do {
//                try {
//                    Message msg = Message.obtain();
//                    msg.what = 5;
//                    mHandler.sendMessage(msg);
//                    mMyUsbDriver.sendStatusMeasure();
//                    Thread.sleep(500);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            } while (true);
//        }
//    }
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    String readMsg = "Read Msg:"+(String)msg.obj+ "\n\n";
                    mDumpTextView.append(readMsg);
                    mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
                    break;
                case 2:
                    String rcvMsg = "receive Msg:"+(String)msg.obj+ "\n\n";
                    mDumpTextView.append(rcvMsg);
                    mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
                    break;
                case 3:
                    String tcpMsg = "send Tcp Msg:"+(String)msg.obj+ "\n\n";
                    mDumpTextView.append(tcpMsg);
                    mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
                    break;
                case 4:
                    String bleMsg = "send bluetooth:"+(String)msg.obj+ "\n\n";
                    mDumpTextView.append(bleMsg);
                    mScrollView.smoothScrollTo(0, mDumpTextView.getBottom());
                    break;

                default:
                    break;
            }

        }
    };

    public Bitmap generateBitmap(String content, int width, int height){
        QRCodeWriter writer = new QRCodeWriter();
        Map<EncodeHintType,String> hint =new HashMap<>();
        hint.put(EncodeHintType.CHARACTER_SET,"utf-8");
        try {
            BitMatrix encode = writer.encode(content, BarcodeFormat.QR_CODE,width,height,hint);
            int []pixels = new int[width*height];
            for(int i=0;i<height;i++){
                for(int j=0;j<width;j++){
                    if(encode.get(j,i)){
                        pixels[i*width+j]=0x00000000;
                    }else {
                        pixels[i*width+j]=0xffffffff;
                    }
                }
            }
            return Bitmap.createBitmap(pixels,0,width,width,height, Bitmap.Config.RGB_565);
        } catch (Exception e){
            e.printStackTrace();
        } return null;
    }


}